App = {
	units : [ "kilos", "kilo", "kg", "gr", "g", "gram", "grams", "liter",
			"liters", "l", "ml", "slice", "slices", "lb", "lbs", "pound",
			"pounds", "pieces", "piece", "cup", "cups", "spoon", "spoons" ],

	ignore : [ "of", "and", ":", "-", ",", "." ],

	getIngredientModel : function(text) {
		var ingredient = {};

		var quantity = [];

		var r = /\d+/g;
		var m;
		while ((m = r.exec(text)) != null) {
			quantity.push(m[0]);
		}

		if (quantity.length == 0) {
			alert("Please add a number that represents the quantity of the ingredient!");
			return;
		} else if (quantity.length > 1) {
			alert("Please add only one number in the text box!");
			return;
		} else {
			ingredient.quantity = quantity[0];
		}

		text = text.replace(ingredient.quantity, '');

		var words = text.split(' ');

		var unit = undefined;
		var name = undefined;

		var possibleIngredients = [];

		for (var i = 0; i < words.length; i++) {
			if (words[i].length > 0) {
				if ($.inArray(words[i], App.ignore) < 0) {
					if ($.inArray(words[i], App.units) >= 0) {
						unit = words[i];
					} else {
						possibleIngredients.push(words[i]);
					}
				}
			}
		}

		if (unit == undefined) {
			unit = "";
		}

		var ingredientName = possibleIngredients.join(" ");

		if ($.inArray(ingredientName, App.ingredients) >= 0) {
			name = ingredientName;
		} else {
			var availableTags = [];

			for (var j = 0; j < App.ingredients.length; j++) {
				var dist = App.levensteinDistance(App.ingredients[j],
						ingredientName);
				availableTags
						.push([
								App.ingredients[j] + " " + quantity + " "
										+ unit, dist ]);
			}

			availableTags.sort(function(a, b) {
				return a[1] - b[1]
			});

			var l = availableTags.length < 5 ? availableTags.length : 5;

			var tags = [];

			for (var o = 0; o < l; o++) {
				tags.push(availableTags[o][0]);
			}

			$("#Ingredient").autocomplete({
				source : tags,
				minLength : 0
			});

			$('#Ingredient').autocomplete('search', '')
		}

		ingredient.name = name;
		ingredient.unit = unit;

		if (ingredient.name === undefined || ingredient.unit === undefined
				|| ingredient.quantity === undefined) {
			return undefined;
		}

		return ingredient;
	},

	levensteinDistance : function(a, b) {
		if (a.length == 0)
			return b.length;
		if (b.length == 0)
			return a.length;

		var matrix = [];

		// increment along the first column of each row
		var i;
		for (i = 0; i <= b.length; i++) {
			matrix[i] = [ i ];
		}

		// increment each column in the first row
		var j;
		for (j = 0; j <= a.length; j++) {
			matrix[0][j] = j;
		}

		// Fill in the rest of the matrix
		for (i = 1; i <= b.length; i++) {
			for (j = 1; j <= a.length; j++) {
				if (b.charAt(i - 1) == a.charAt(j - 1)) {
					matrix[i][j] = matrix[i - 1][j - 1];
				} else {
					matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // substitution
					Math.min(matrix[i][j - 1] + 1, // insertion
					matrix[i - 1][j] + 1)); // deletion
				}
			}
		}

		return matrix[b.length][a.length];
	},

	bindEvents : function() {
		$(document)
				.on(
						'keypress',
						'#Ingredient',
						function(e) {
							if (e.which == 13) {
								if (this.value !== undefined
										&& this.value !== '') {

									var text = this.value;
									var view = App.getIngredientModel(text);

									if (view !== undefined) {
										$("#IngredientsList")
												.append(
														Mustache
																.render(
																		"<div class='ingredient'><span class='name'>{{name}}</span>&nbsp;<span class='quantity'>{{quantity}}</span>&nbsp;<span class='unit'>{{unit}}</span><image class='remove' src='/img/remove.png' /></div>",
																		view));
										this.value = '';
									}
								}
							}
							// console.log(String.fromCharCode(e.which));
							// console.log(e.which);
						});

		$(document).on('click', '.remove', function() {
			var $ingr = $(this).closest('.ingredient');
			$ingr.hide('slow', function() {
				$ingr.remove();
			});
		});

		$(document).on('click', '#GetRecipes', function() {
			var ingredientList = [];
			$("#IngredientsList .ingredient").each(function() {

				ingredientList.push({
					name : $(this).find(".name").html(),
					unit : $(this).find(".unit").html(),
					quantity : $(this).find(".quantity").html(),
				});
			});

			if (ingredientList.length == 0) {
				$("#Recipes").html("No recipes found..");
			} else {
				console.log(JSON.stringify(ingredientList));
				$.ajax({
					url : '/recommend',
					type : 'post',
					dataType : 'json',
					success : function(data) {
						var recipesList = eval(data);


						$("#Recipes").html('<div id="accordion"></div>');
						
						var $accordion = $('#accordion');						
													
						for(var i = 0; i < recipesList.length; i++){
							recipesList[i].text = recipesList[i].text.replace(/\n/g, "<br>");
							
							$accordion.append(Mustache
							.render(
									"<h3>" + eval(i + 1) +". {{name}}</h3><div><img src='{{imageUrl}}'/><br/><br/><b>Cooking time:</b>{{cookingTime}} min</br></br> <b>Steps:</b></br>{{text}}<br/><br/><b>Original URL:</b><a href='{{url}}' target='_blank'>{{url}}</a></div>",
									recipesList[i]));
						}

						$accordion.accordion({
							heightStyle : "fill"
						});
					},

					contentType : 'application/json',
					data : JSON.stringify(ingredientList)
				});
			}
		});
	}
};

$(document).ready(function() {
	// Get the ingredients
	$.ajax("ingredients").done(function(ingr) {
		App.ingredients = ingr;
	}).fail(function() {
		alert("Error getting the ingredients!");
	});

	App.bindEvents();
});
